#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <sys/time.h>
 
#include "data_type.h"
#include "cube.h"
#include "cube_define.h"
#include "cube_record.h"

#include "user_define.h"
#include "action_define.h"
#include "key_event.h"
// add para lib_include
int key_event_init(void * sub_proc, void * para)
{
	int ret;
	// add yorself's module init func here
	return 0;
}
int key_event_start(void * sub_proc, void * para)
{
	int ret;
	void * recv_msg;
	int type;
	int subtype;
	// add yorself's module exec func here
	while(1)
	{
		usleep(time_val.tv_usec);
		ret=ex_module_recvmsg(sub_proc,&recv_msg);
		if(ret<0)
			continue;
		if(recv_msg==NULL)
			continue;
		type=message_get_type(recv_msg);
		subtype=message_get_subtype(recv_msg);
		if(!memdb_find_recordtype(type,subtype))
		{
			printf("message format (%d %d) is not registered!\n",
			message_get_type(recv_msg),message_get_subtype(recv_msg));
			continue;
		}
		if((type==TYPE(USER_DEFINE))&&(subtype==SUBTYPE(USER_DEFINE,RETURN)))
		{
			ret=proc_keyevent_return(sub_proc,recv_msg);
		}
		else if((type==TYPE(ACTION_DEFINE))&&(subtype==SUBTYPE(ACTION_DEFINE,HANDSHAKE)))
		{
			ret=proc_keyevent_shakehand(sub_proc,recv_msg);
		}
		else if((type==TYPE(MESSAGE))&&(subtype==SUBTYPE(MESSAGE,BASE_MSG)))
		{
			ret=proc_keyevent_send(sub_proc,recv_msg);
		}
	}
	return 0;
}

	
int proc_keyevent_return(void * sub_proc,void * recv_msg)
{
	int ret;
	RECORD(USER_DEFINE,RETURN) * login_return;
	RECORD(MESSAGE,INSTANCE_INFO) * instance_info;
	char user_name[DIGEST_SIZE];
	void * new_msg;
	
	BYTE local_uuid[DIGEST_SIZE];	
	char proc_name[DIGEST_SIZE];	

	ret=message_get_record(recv_msg,&login_return,0);
	if(ret<0)
		return ret;

    if(login_return->return_code!=SUCCEED)
        return -EINVAL;

	instance_info=Talloc0(sizeof(*instance_info));
	if(instance_info==NULL)
		return -ENOMEM;
	
	proc_share_data_getvalue("proc_name",instance_info->proc_name);
	proc_share_data_getvalue("user_name",instance_info->user_name);
	//proc_share_data_getvalue("uuid",instance_info->node_uuid);

	new_msg=message_create(TYPE_PAIR(USER_DEFINE,RETURN),recv_msg);	
	if(new_msg==NULL)
		return -EINVAL;
	ret=message_add_record(new_msg,login_return);
	if(ret<0)
		return ret;

	ret=message_add_expand_data(new_msg,TYPE_PAIR(MESSAGE,INSTANCE_INFO),instance_info);
	if(ret<0)
		return ret;
    
	ret=ex_module_sendmsg(sub_proc,new_msg);
	return ret;
}

int proc_keyevent_shakehand(void * sub_proc,void * recv_msg)
{
	int ret;
	RECORD(ACTION_DEFINE,HANDSHAKE) * action_info;
	RECORD(GENERAL_RETURN,STRING) * getkey_info;
	RECORD(MESSAGE,INSTANCE_INFO) * instance_info;
	char user_name[DIGEST_SIZE];
	void * new_msg;
	
	BYTE local_uuid[DIGEST_SIZE];	
	char proc_name[DIGEST_SIZE];	

	ret=message_get_record(recv_msg,&action_info,0);
	if(ret<0)
		return ret;

    if(action_info->handshake_type==KEY_EXCHANGE)
        return proc_keyevent_key_exchange(sub_proc,recv_msg);

    return -EINVAL;
}

int proc_keyevent_key_exchange(void * sub_proc,void * recv_msg)
{
	RECORD(ACTION_DEFINE,HANDSHAKE) * action_info;
	RECORD(GENERAL_RETURN,STRING) * remotekey_info;
	char user_name[DIGEST_SIZE];
	void * new_msg;
	int ret;
	
	BYTE local_uuid[DIGEST_SIZE];	
	char proc_name[DIGEST_SIZE];	

	ret=message_get_record(recv_msg,&action_info,0);
	if(ret<0)
		return ret;

	remotekey_info=Talloc0(sizeof(*remotekey_info));
	if(remotekey_info==NULL)
		return -ENOMEM;
    remotekey_info->return_value=dup_str(action_info->server,DIGEST_SIZE);
    remotekey_info->name=dup_str("key_exchange",0);

	new_msg=message_create(TYPE_PAIR(GENERAL_RETURN,STRING),recv_msg);	
//	ret=message_add_expand_data(recv_msg,TYPE_PAIR(MESSAGE,INSTANCE_INFO),instance_info);	
	if(ret<0)
		return ret;
	ret=message_add_record(new_msg,remotekey_info);
	if(ret<0)
		return ret;	
	ret=message_add_expand_data(recv_msg,TYPE_PAIR(ACTION_DEFINE,HANDSHAKE),action_info);	
	if(ret<0)
		return ret;
	ret=ex_module_sendmsg(sub_proc,new_msg);
	return ret;
}

int proc_keyevent_send(void * sub_proc,void * recv_msg)
{
	int ret;
	RECORD(MESSAGE,BASE_MSG) * login_sendkey;
	RECORD(MESSAGE,INSTANCE_INFO) * instance_info;
	char user_name[DIGEST_SIZE];
	void * new_msg;
	
	BYTE local_uuid[DIGEST_SIZE];	
	char proc_name[DIGEST_SIZE];	

	ret=message_get_record(recv_msg,&login_sendkey,0);
	if(ret<0)
		return ret;
	if(Strncmp("piksend",login_sendkey->message,DIGEST_SIZE) !=0)
    {
        print_cubeerr("wrong command %s",login_sendkey->message);
        return -EINVAL;
    }
	instance_info=Talloc0(sizeof(*instance_info));
	if(instance_info==NULL)
		return -ENOMEM;
	
	proc_share_data_getvalue("proc_name",instance_info->proc_name);
	proc_share_data_getvalue("user_name",instance_info->user_name);
	proc_share_data_getvalue("uuid",instance_info->node_uuid);

	new_msg=message_create(TYPE_PAIR(MESSAGE,INSTANCE_INFO),recv_msg);	
//	ret=message_add_expand_data(recv_msg,TYPE_PAIR(MESSAGE,INSTANCE_INFO),instance_info);	
//	if(ret<0)
//		return ret;
	ret=message_add_record(new_msg,instance_info);
	if(ret<0)
		return ret;	
	ret=ex_module_sendmsg(sub_proc,new_msg);
	return ret;
}
